/**
 * Software License, Version 1.0 Copyright 2003 The Trustees of Indiana
 * University. All rights reserved. Redistribution and use in source and binary
 * forms, with or without modification, are permitted provided that the
 * following conditions are met: 1) All redistributions of source code must
 * retain the above copyright notice, the list of authors in the original source
 * code, this list of conditions and the disclaimer listed in this license; 2)
 * All redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the disclaimer listed in this license in the
 * documentation and/or other materials provided with the distribution; 3) Any
 * documentation included with all redistributions must include the following
 * acknowledgement: "This product includes software developed by the Community
 * Grids Lab. For further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/." Alternatively, this acknowledgement may
 * appear in the software itself, and wherever such third-party acknowledgments
 * normally appear. 4) The name Indiana University or Community Grids Lab or
 * NaradaBrokering, shall not be used to endorse or promote products derived
 * from this software without prior written permission from Indiana University.
 * For written permission, please contact the Advanced Research and Technology
 * Institute ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202. 5)
 * Products derived from this software may not be called NaradaBrokering, nor
 * may Indiana University or Community Grids Lab or NaradaBrokering appear in
 * their name, without prior written permission of ARTI. Indiana University
 * provides no reassurances that the source code provided does not infringe the
 * patent or any other intellectual property rights of any other entity. Indiana
 * University disclaims any liability to any recipient for claims brought by any
 * other entity based on infringement of intellectual property rights or
 * otherwise. LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH
 * NO WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY
 * GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 * INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 * INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 * "VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 * LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 * ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 * GENERATED USING SOFTWARE.
 */
package cgl.narada.transport.http;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;

import javax.net.ServerSocketFactory;

import cgl.narada.transport.TransportException;
import cgl.narada.transport.sslHttpBase.Transport;
import cgl.narada.transport.sslHttpBase.TransportFactory;
import cgl.narada.util.logging.Logger;
import cgl.narada.util.logging.LoggerFactory;
import cgl.narada.util.proxy.WinProxyDetection;

/**
 * @author Hongbin Liu 
 * @author Harshawardhan Gadgil
 * $Date$ $Revision$
 */
public class HTTPTransportFactoryImpl implements TransportFactory {

	final static Logger log = LoggerFactory
			.getLogger(HTTPTransportFactoryImpl.class.getName());

	private ServerSocket serverSocket;
	private Properties defaultProperties = new Properties();
	private ServerSocketFactory serverSocketFactory = null;
	// TODO HTTPTransportImpl should make this one variable

	// HG: Should make this port as 0, so that clients can listen on next
	// available port
	private static int serverListeningPort = 0;

	/**
	 * @return HTTTransportImpl instance
	 */
	public Transport createTransportInstance() {
		Transport t = new HTTPTransportImpl();
		// defaultProperties.list(System.out);
		// t.setProperties(defaultProperties);
		return t;
	}

	/**
	 *
	 */
	public void setProperties(Properties properties) {
		defaultProperties.putAll(properties);
	}

	/**
	 * Starts a listening socket.
	 */
	public void initialize() throws TransportException {
		String port = defaultProperties.getProperty("acceptor.http.port");
		// String port = defaultProperties.getProperty("portnum");
		try {
			if (port != null) serverListeningPort = Integer.parseInt(port);
			if (serverSocketFactory == null) {
				serverSocket = new ServerSocket(serverListeningPort);
			}
			else {
				serverSocket = serverSocketFactory
						.createServerSocket(serverListeningPort);
			}
		}
		catch (Exception e) {
			throw new TransportException("IOException=" + e.getMessage());
		}

		String os = System.getProperty("os.name");

		if (os.toLowerCase().indexOf("windows") >= 0) {
			WinProxyDetection detection = new WinProxyDetection();
			String domain = detection.GetDomainWorkgroupName();
			String hostname = detection.GetHostName();
			log.info("Detected windows domain: " + domain);
			log.info("Detected windows hostname: " + hostname);
			defaultProperties.setProperty("domain", domain);
			defaultProperties.setProperty("hostname", hostname);
		}
		System.out.println("HTTP Acceptor created on port "
				+ serverListeningPort);
	}

	/**
	 * @return HTTPTransportImpl instance
	 */
	// wait for connetion request vs. createTransportInstance initiate conn
	// request
	public Transport accept() throws TransportException {
		if (serverSocket == null) {
			throw new TransportException("ServerSocket is null");
		}

		try {
			Socket socket = serverSocket.accept();
			socket.setSoLinger(false, 0);
			socket.setTcpNoDelay(true);
			return new HTTPTransportImpl(socket);
		}
		catch (IOException e) {
			throw new TransportException("IOException=" + e.getMessage());
		}
	}
}
